Metadata-Version: 2.1
Name: qsea
Version: 0.1.11
Summary: Convenient way to work with Qlik Sense Engine API from Python
Home-page: https://github.com/ncthuc/qsea
Download-URL: https://pypi.org/project/qsea/
Author: Lev Biriukov
Author-email: lbiryukov@gmail.com
License: MIT
Keywords: QlikSense,Qlik
Description-Content-Type: text/markdown
License-File: LICENSE.txt

## Title

QSEA refers to the Qlik Sense Engine API. 

## Description

QSEA intends to automate most basic operations with Qlik Sense Enterprise apps in a pythonic way.
Quickly view and edit variables, master measures and dimensions, and main sheet objects. For example, you can replace variables in all master measures of your app in one line

```python
for ms in App.measures: ms.update(definition = replace(ms.definition, '$(var1)', '$(var2)'))
```
or quickly move all measures from one app to another:

```python
for ms in App1.measures: App2.measures.add(name = ms.name, definition = ms.definition)
```

```python
Installation

pip install qsea
```

## Getting started

QSEA uses Qlik Sense Engine API via the Qlik Sense Proxy Service as a main engine, so you'll need correct credetentials to start working with it. Please refer to 
https://help.qlik.com/en-US/sense-developer/May2023/Subsystems/EngineAPI/Content/Sense_EngineAPI/GettingStarted/connecting-to-engine-api.htm
https://help.qlik.com/en-US/cloud-services/Subsystems/Hub/Content/Sense_Hub/Admin/mc-generate-api-keys.htm
for help.

Your credetentials should look something like this
```python
header_user = {'Authorization': 'Bearer <API KEY>'}
qlik_url = "wss://server.domain.com[/virtual proxy]/app/"
```

Now we can connect to the Qlik Server:
```python
conn = qsea.Connection(header_user, qlik_url)
```

Let's create an App object which is a representation of the application in Qlik Sense.
```python
app = qsea.App(conn, 'MyAppName')
```

By default the App class object is almost empty. You have to use load() function to make use of it:
```python
app.load()
```

Now all variables, master measuers and dimensions are uploaded to our App object. We can access them by their name:
```python
var = app.variables['MyVar']
var.definition
```

```python
ms = app.measures['MyMeasure']
ms.label_expression
```

or overview their properties via pandas dataframe:
```python
app.dimensions.df
```

Now we can create a new measure:
```python
app.measures.add(name = 'MyMeasure', definition = 'sum(Sales)')
```

or update a variable:
```python
var.update(definition = 'sum(Sales)')
```

Save the app in order for changes to reflect in the real Qlik Sense application 
```python
app.save()
```

Let's copy the set of master dimensions in a new app:
```python
source_app = qsea.App(conn, 'Source AppName')
target_app = qsea.App(conn, 'Target AppName')
source_app.load()
target_app.load()

for dim in source_app.dimensions:
    if dim.name not in [target_dim.name for target_dim in target_app.dimensions]: target_app.dimensions.add (name = dim.name, definition = dim.definition)

target_app.save()
```

Note that as it stands, only basic properties, such as names, definitions and a couple of others can be accesed via qsea module.

Most of read-only operations (such as loading apps) can be performed on published apps. However, it is recommnded to modify objects only in unpublished apps.

Besides master measures, master dimensions and variables, tables and charts in the  can be also uploaded.

```python
app.load()
sh = app.sheets['MySheet']
sh.load()
for obj in sh.objects:
    for ms on obj.measures:
        print(ms.definition)
```

Good luck!

### App class
The class, representing the Qlik Sense application. This is the main object to work with. The class is empty when created; run the load() function to make use of it.

#### load()
Loads data from the Qlik Sense application into an App object.

Args:
* depth (int): depth of loading
    - 1 - app + variables, measures, sheets, fields, dimensions (default value)
    - 2 - everything from 1 + sheet objects (tables, sharts etc.)
    - 3 - everything from 2 + object dimensions and measures

Different levels can be useful while working with large apps for which full load can be time-consuming.
Only dimensions and measures from standard Qlik Sense charts are uploaded. Uploading dimensions from filter panes is currently not supported.

```
App.load(level = 3)
```

#### save()
You have to save the App object for the changes to be reflected in the Qlik Sense Application. Note that it is recommnded to modify objects only in unpublished apps.
```
App.save()
```

#### reload_data()
Starts the script of reloading data into the Qlik Sense Application.
```
App.reload_data()
```

#### children
app.load(level = 1) creates several objects of AppChildren class

### AppChildren class
The class contains collections of master objects in the Qlik Sense Application:
* app.variables: a collection of Variable class objects, representing the variables of the Qlik Sense application
* app.measures: a collection of Measure class objects, representing the master measures of the Qlik Sense application
* app.dimensions: a collection of Dimension class objects, representing the master dimensions of the Qlik Sense application
* app.sheets: a collection of Sheet class objects, representing the sheets of the Qlik Sense application 
* app.fields: a collection of Field class objects, representing the fields of the Qlik Sense application

You can access the main information in pandas dataframe about each group of objects via .df:
```python 
app.variables.df
``` 
#### add()
Use `add()` function to add new variables, master measures or master dimensions to the app. 

Args:
* name (str): Name of the object to be created.
* definition (str): Definition of the object to be created.
* description (str, optional): Description of the object to be created. Defaults to ''.
* label (str, optional): Label of the object to be created. Defaults to ''.
* label_expression (str, optional): Label expression of the object to be created. Defaults to ''.
* format_type (str, optional): Format type of the object to be created. Defaults to 'U'.
    - 'U' for auto
    - 'F' for number
    - 'M' for money
    - 'D' for date
    - 'IV' for duration
    - 'R' for other
* format_ndec (int, optional): Number of decimals of the object to be created. Defaults to 10.
* format_use_thou (int, optional): Use thousands separator of the object to be created. Defaults to 0.
* format_dec (str, optional): Decimal separator of the object to be created. Defaults to ','.
* format_thou (str, optional): Thousands separator of the object to be created. Defaults to ''.

Returns: True if the object was created successfully, False otherwise.
Only parametres applicable to the certain class will be used
```
App.variables.add(name = 'MyVar', definition = 'sum(Sales)')
App.measures.add(name = 'MyFunc', definition = 'sum(Sales)', format_type = 'F')
App.dimensions.add(name = 'MyDim', definition = 'Customer')
```

### Variable class
The class, representing variables of the application. Member of the App.variables collection.
You can call the exact variable via it's name or iterate them
```
var = app.variables['MyVar']
print(var.definition)

for var in app.variables:
    if var.definition == 'sum(Sales)': var.update(name = 'varSales')
```
#### variable properties
* name - that's the name of the variable you generally use in the Qlik Sense interface
* definition - the formula behind the variable
* description - the description of the variable
* auxiliary
    - handle - the internal handle of the object in Qlik Sense Engine API; can be  used to access the variable via `query()` function
    - app_handle - the handle of the parent App object
    - id - Qlik Sense internal id of the variable
    - created_date - creation date of the variable, as stored in Qlik Sense
    - modified_date - date of the last modification of the variable, as stored in Qlik Sense
    - script_created - True if the variable is created via the application load script, False if not

#### update()
Updates the variable on the Qlik Sense Server

Args:
    definition (str): new definition of the variable (leave None to keep the old value)
    description (str): new description of the variable (leave None to keep the old value)

Returns:
    True if the variable was updated successfully, False otherwise
```
var = app.variables['MyVar']
var.update(definition = 'sum(Sales)')
app.save()
```

#### delete()
Deletes the variable from the Qlik Sense Server

Returns:
    True if the variable was deleted successfully, False otherwise

```
var = app.variables['MyVar']
var.delete()
app.save()
```

#### rename()
Renames the variable on the Qlik Sense Server. Since there is no direct method to rename the variable, it basically deletes the variable with the old name, and creates a new one, with the new name.

Returns:
    True if the variable is renamed succesfully, False otherwise

```
var = app.variables['MyVar']
var.rename('MyVarNewName')
app.save()
```

### Measure class
The class, representing measures of the application. Member of the App.measures collection.
You can call the exact measure via it's name or iterate them
```
ms = app.variables['MyVar']
print(ms.definition)

for ms in app.measures:
    if ms.definition == 'sum(Sales)': ms.update(name = 'Sales')
```
#### measure properties
* name - that's the name of the variable you generally use in the Qlik Sense interface
* definition - the formula behind the variable
* description - the description of the variable
* label - 
* auxiliary
    - handle - the internal handle of the object in Qlik Sense Engine API; can be  used to access the variable via `query()` function
    - app_handle - the handle of the parent App object
    - id - Qlik Sense internal id of the variable
    - created_date - creation date of the variable, as stored in Qlik Sense
    - modified_date - date of the last modification of the variable, as stored in Qlik Sense
    - script_created - True if the variable is created via the application load script, False if not

#### update()

#### delete()

#### rename()

### Dimension class

#### update()

#### delete()

#### rename()

### Sheet class

#### load()

### Field class

### Object class 

#### load()

### ObjectChildren class

Adding measures and dimensions to app objects is not supported yet

### ObjectMeasure class

#### update()

#### delete()

### ObhectDimension class

#### update()

#### delete()

